﻿Imports FairShop.Objects
Imports System.Windows.Forms

Public Class Grafiek
    Inherits Control

    Const WIDTH_LEFT_SCALE As Integer = 40
    Const WIDTH_LEGENDE As Integer = 80
    Const HEIGHT_BOTTOM_SCALE As Integer = 20
    Const FONT_SIZE As Integer = 8

    Private _font As Font
    Private _area As GrafiekAreaBase

#Region "Public property's"

    Public Property Type() As GrafiekAreaBase.GrafiekType
        Get
            If (_area Is Nothing) Then
                Return Nothing
            Else
                Return _area.Type
            End If
        End Get
        Set(ByVal value As GrafiekAreaBase.GrafiekType)
            If (_area IsNot Nothing) Then
                Me.Controls.Remove(_area)
            End If
            Select Case value
                Case GrafiekAreaBase.GrafiekType.Pin
                    _area = New GrafiekAreaPin()
                Case GrafiekAreaBase.GrafiekType.Blok
                    _area = New GrafiekAreaBlok()
                Case GrafiekAreaBase.GrafiekType.Lijn
                    _area = New GrafiekAreaLijn()
            End Select
            _area.Left = WIDTH_LEFT_SCALE
            _area.Top = 1
            _area.Width = GrafiekBreedte - 1
            _area.Height = GrafiekHoogte - 1
            Me.Controls.Add(_area)
        End Set
    End Property

    Private ReadOnly Property GrafiekBreedte() As Integer
        Get
            Return Me.Width - WIDTH_LEFT_SCALE - WIDTH_LEGENDE
        End Get
    End Property

    Private ReadOnly Property GrafiekHoogte() As Integer
        Get
            Return Me.Height - HEIGHT_BOTTOM_SCALE
        End Get
    End Property

    Private ReadOnly Property MaxWaarde() As Decimal
        Get
            If (_area Is Nothing) Then
                Return 0
            Else
                Return _area.Data.MaxWaarde
            End If
        End Get
    End Property

    Private ReadOnly Property MinWaarde() As Decimal
        Get
            If (_area Is Nothing) Then
                Return 0
            Else
                Return _area.Data.MinWaarde
            End If
        End Get
    End Property

#End Region

#Region "Constructor en initialisatie"

    Public Sub New()
        _font = New Font(FontFamily.GenericSansSerif, FONT_SIZE)
    End Sub

#End Region

#Region "Event handlers"

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        MyBase.OnPaint(e)
        e.Graphics.DrawRectangle(Pens.Gray, Me.ClientRectangle) ' ook @design time
        If (_area Is Nothing) Then Return
        If (_area.Data Is Nothing) Then Return
        If _area.Data.DataTable.Count = 0 Then
            e.Graphics.FillRectangle(Brushes.Red, Me.ClientRectangle) ' TODO
            Return
        End If

        If (_area.Data.HorizontalSpan = 1) Then
            e.Graphics.FillRectangle(Brushes.Yellow, Me.ClientRectangle) ' TODO
            Return
        Else
            EraseCanvas(e.Graphics)
            DrawVerticalScale(e.Graphics, _area.Origin)
            DrawHorizontalScale(e.Graphics, _area.Data.StartDatum)
            DrawLegend(e.Graphics)
            _area.Invalidate()
        End If
    End Sub

#End Region

#Region "Public methods"

    Public Sub SetData(ByVal ds As HistoriekDataSet, ByVal startwaarde As Integer)
        If (_area IsNot Nothing) Then
            _area.Data = New GrafiekData(ds, Me.Type, startwaarde)
        End If
    End Sub

#End Region

#Region "Private methods"

    Private Sub EraseCanvas(ByVal g As Graphics)
        g.FillRectangle(Brushes.White, Me.ClientRectangle)
        g.DrawRectangle(Pens.Black, 0, 0, Me.Width - 1, Me.Height - 1)
    End Sub

    Private Sub DrawVerticalScale(ByVal g As Graphics, ByVal origin As Integer)
        Dim verticalIntervalInPixels As Double = _area.GridLineIntervalVertical

        If (verticalIntervalInPixels > 0D) Then
            Dim sf As New StringFormat()
            sf.Alignment = StringAlignment.Far

            For i As Integer = -Convert.ToInt32((GrafiekHoogte - origin) / verticalIntervalInPixels) + 1 To Convert.ToInt32(origin / verticalIntervalInPixels)
                Dim text As String = (i * _area.ValueIntervalPerGridline).ToString()
                Dim h As Integer = Convert.ToInt32(origin - i * verticalIntervalInPixels)
                g.DrawString(text, _font, Brushes.Black, WIDTH_LEFT_SCALE, h - _font.Height \ 2, sf)
            Next
        End If
    End Sub

    Private Sub DrawHorizontalScale(ByVal g As Graphics, ByVal startDatum As Date)
        Dim horizontalIntervalInPixels As Integer = _area.GridLineIntervalHorizontal

        If (horizontalIntervalInPixels > 0D) Then
            Dim sf As New StringFormat()
            sf.Alignment = StringAlignment.Center

            For i As Integer = 0 To Convert.ToInt32(Me.Width / horizontalIntervalInPixels) + 1
                Dim x As Integer = WIDTH_LEFT_SCALE + i * horizontalIntervalInPixels
                Dim datum As Date = startDatum.AddMonths(i * _area.MonthsPerGridline)
                Dim text As String = datum.ToString("M/yy")
                g.DrawString(text, _font, Brushes.Black, x, GrafiekHoogte + 2, sf)
            Next
        End If
    End Sub

    Private Sub DrawLegend(ByVal g As Graphics)
        Dim legendLeft As Integer = Me.Width - WIDTH_LEGENDE
        For i As Integer = 0 To _area.Data.Values.Count - 1
            Dim serie As String = _area.Data.Values(i)
            Dim color As Color = _area.Data.GetColor(serie)
            Dim serieTop As Integer = i * 22 + 5
            g.FillRectangle(New SolidBrush(color), legendLeft, serieTop, 10, 10)
            g.DrawString(serie, _font, Brushes.Black, legendLeft + 15, serieTop)
        Next
    End Sub

#End Region

End Class
